<!--  
swiper轮播专用canvas批改组件
组件使用说明：
1. props: 
   - imgurl: 图片地址（网络或本地）
   - list: 批改数据数组
   - swiperIndex: 轮播索引，用于区分不同的canvas实例
   - attachs: 原始数据
2. events:
   - @updateList: 当用户手动纠错或删除标注时触发，返回更新后的list数据
   
使用示例：
<canvastest-swiper 
  :imgurl="imageUrl" 
  :list="correctList" 
  :swiperIndex="index"
  @updateList="handleListUpdate"
></canvastest-swiper>
-->
<template>
	<view class="container">
		<canvas :canvas-id="`myCanvas${swiperIndex}`" :id="`myCanvas${swiperIndex}`" type="2d"
			@touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
			:style="canvasStyle"></canvas>
	</view>
</template>

<script>
import {
	getErrorChars,
	getMissingChars,
	getCharCenter,
	isClickInChar,
	convertToCanvasCoord,
	convertToOriginalCoord,
	calculateStyles
} from "@/utils/correctUtils.js"

export default {
	props: {
		imgurl: {
			type: String,
			required: true
		},
		list: {
			type: Array,
			required: true,
			default: () => []
		},
		swiperIndex: {
			type: Number,
			required: true,
			default: 0
		},
		// 添加attachs prop用于接收原始数据
		attachs: {
			type: Object,
			default: null
		}
	},
	data() {
		return {
			canvasNode: null,
			ctx: null,
			dpr: 1,
			// 图片相关
			bgImgPath: '',
			originalImageWidth: 0,
			originalImageHeight: 0,
			canvasWidth: 0,
			canvasHeight: 0,
			canvasDisplayWidth: 0,
			canvasDisplayHeight: 0,
			// 样式配置
			circleSize: 25,
			lineWidth: 4,
			fontSize: 50,
			// 错别字数据
			errorChars: [],
			missingChars: [],
			markedChars: [], // 已标记的字符
			// 添加可点击字符数据
			clickableChars: [], // 来自attachs.imageInfos的chars数据
			originalAttachs: null, // 存储原始attachs数据
			// 交互相关
			touchStartX: 0,
			touchStartY: 0,
			isMoving: false,
			moveThreshold: 10
		}
	},
	computed: {
		canvasStyle() {
			// 如果有原图尺寸，按比例计算显示尺寸
			if (this.canvasWidth && this.canvasHeight) {
				// 宽度固定为520rpx，高度按比例计算，但限制最大高度
				const fixedWidth = 520
				const maxHeight = 800 // 限制最大高度为800rpx，与swiper容器高度一致
				const scale = fixedWidth / this.canvasWidth
				const displayWidth = fixedWidth
				const displayHeight = Math.min(this.canvasHeight * scale, maxHeight)

				console.log(`Canvas ${this.swiperIndex} 尺寸计算:`, {
					原图宽度: this.canvasWidth,
					原图高度: this.canvasHeight,
					显示宽度: displayWidth,
					显示高度: displayHeight,
					缩放比例: scale,
					最大高度限制: maxHeight
				})

				return `width: ${displayWidth}rpx; height: ${displayHeight}rpx; border: 1px solid #ccc;`
			} else {
				return 'width: 520rpx; height: 600rpx; border: 1px solid #ccc;'
			}
		}
	},
	watch: {
		imgurl: {
			handler(newVal, oldVal) {
				if (newVal && newVal !== oldVal) {
					console.log(`Canvas ${this.swiperIndex} - 图片URL变化，强制重新初始化:`, {
						新URL: newVal,
						旧URL: oldVal
					});
					// 清理之前的数据
					this.resetCanvasData();
					this.loadImage();
				}
			},
			immediate: true
		},
		list: {
			handler(newVal, oldVal) {
				if (newVal && newVal.length > 0) {
					console.log(`Canvas ${this.swiperIndex} - 接收到新的list数据:`, newVal)

					// 检查数据是否真的发生了变化
					const hasChanged = JSON.stringify(newVal) !== JSON.stringify(oldVal);
					if (hasChanged) {
						console.log(`Canvas ${this.swiperIndex} - 数据确实发生变化，重新处理`);
						// 清理之前的标记数据
						this.resetCanvasData();
					}

					// 如果数据看起来像是直接的errorJuZis格式，给出提示
					const firstItem = newVal[0]
					if (firstItem.reason !== undefined && firstItem.correct !== undefined && firstItem.locations !==
						undefined) {
						console.log(`Canvas ${this.swiperIndex} - 检测到可能的errorJuZis直接格式，需要转换为chars格式`)
					}

					this.processCorrectData()

					// 如果canvas已经准备好，强制重新绘制
					if (this.ctx && this.bgImgPath && hasChanged) {
						console.log(`Canvas ${this.swiperIndex} - 强制重新绘制canvas`);
						setTimeout(() => {
							this.redraw();
						}, 100);
					}
				}
			},
			immediate: true,
			deep: true
		},
		// 添加对attachs的监听
		attachs: {
			handler(newVal, oldVal) {
				if (newVal && JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
					console.log(`Canvas ${this.swiperIndex} - 接收到新的attachs数据:`, newVal)
					this.processAttachsData(newVal)
				}
			},
			immediate: true,
			deep: true
		}
	},
	onReady() {
		// 延迟执行，确保DOM完全准备好
		setTimeout(() => {
			this.initCanvas()
		}, 200 + this.swiperIndex * 100) // 根据索引错开初始化时间
	},
	methods: {
		/**
		 * 清理之前的数据，重置canvas状态
		 */
		resetCanvasData() {
			console.log(`Canvas ${this.swiperIndex} - 重置canvas数据`);
			// 保留canvas节点和context，只清理数据
			this.errorChars = [];
			this.missingChars = [];
			this.markedChars = [];
			this.clickableChars = [];
			this.originalAttachs = null;

			// 重置图片相关数据
			this.bgImgPath = '';
			this.originalImageWidth = 0;
			this.originalImageHeight = 0;
			this.canvasWidth = 0;
			this.canvasHeight = 0;

			// 清空canvas（如果已初始化）
			if (this.ctx) {
				this.ctx.clearRect(0, 0, this.canvasNode.width, this.canvasNode.height);
			}
		},

		/**
		 * 强制重新初始化canvas（用于处理数据完全变化的情况）
		 */
		forceReinitialize() {
			console.log(`Canvas ${this.swiperIndex} - 强制重新初始化canvas`);

			// 完全重置所有数据
			this.resetCanvasData();

			// 如果有图片URL，重新加载
			if (this.imgurl) {
				console.log(`Canvas ${this.swiperIndex} - 重新加载图片:`, this.imgurl);
				this.loadImage();
			}

			// 如果有list数据，重新处理
			if (this.list && this.list.length > 0) {
				console.log(`Canvas ${this.swiperIndex} - 重新处理数据:`, this.list.length);
				this.processCorrectData();
			}

			// 如果有attachs数据，重新处理
			if (this.attachs) {
				console.log(`Canvas ${this.swiperIndex} - 重新处理attachs`);
				this.processAttachsData(this.attachs);
			}
		},

		/**
		 * 加载网络图片
		 */
		async loadImage() {
			if (!this.imgurl) {
				console.log(`Canvas ${this.swiperIndex} - 没有图片URL，跳过加载`);
				return
			}

			console.log(`Canvas ${this.swiperIndex} - 开始加载图片:`, this.imgurl);

			try {
				let imagePath = this.imgurl

				// 判断是否为网络图片
				if (this.imgurl.startsWith('http')) {
					console.log(`Canvas ${this.swiperIndex} - 检测到网络图片，开始下载`);
					// 检查网络状态
					const networkInfo = await this.getNetworkType()

					if (networkInfo.networkType === 'none') {
						throw new Error('网络连接不可用')
					}

					// 下载网络图片到本地
					const downloadRes = await this.downloadFile(this.imgurl)
					imagePath = downloadRes.tempFilePath
					console.log(`Canvas ${this.swiperIndex} - 图片下载完成，本地路径:`, imagePath);
				} else {
					console.log(`Canvas ${this.swiperIndex} - 使用本地图片路径:`, imagePath);
				}

				// 获取图片信息
				console.log(`Canvas ${this.swiperIndex} - 获取图片信息:`, imagePath);
				const imageInfo = await this.getImageInfo(imagePath)

				this.bgImgPath = imagePath
				this.originalImageWidth = imageInfo.width
				this.originalImageHeight = imageInfo.height

				// 直接使用原图尺寸作为Canvas尺寸
				this.canvasWidth = imageInfo.width
				this.canvasHeight = imageInfo.height

				console.log(`Canvas ${this.swiperIndex} - 图片信息获取成功:`, {
					图片路径: imagePath,
					宽度: imageInfo.width,
					高度: imageInfo.height,
					canvas宽度: this.canvasWidth,
					canvas高度: this.canvasHeight
				});

				// 根据图片大小设置样式参数，考虑到现在canvas会缩小
				const scale = Math.min(520 / this.canvasWidth, 1) // 计算缩放比例，使用520rpx作为最大宽度
				if (this.canvasWidth > 2000) {
					this.lineWidth = Math.max(2, 4 * scale)
					this.circleSize = Math.max(15, 60 * scale)
					this.fontSize = Math.max(30, 120 * scale)
				} else {
					this.lineWidth = Math.max(1, 2 * scale)
					this.circleSize = Math.max(10, 25 * scale)
					this.fontSize = Math.max(20, 50 * scale)
				}

				// 如果canvas已经初始化，直接设置，否则等待初始化完成
				if (this.canvasNode && this.ctx) {
					console.log(`Canvas ${this.swiperIndex} - Canvas已初始化，直接设置`);
					this.setupCanvas()
				} else {
					console.log(`Canvas ${this.swiperIndex} - Canvas未初始化，等待初始化完成`);
				}
			} catch (error) {
				console.error(`Canvas ${this.swiperIndex} - 图片加载失败:`, error)

				// 如果canvas已准备好，绘制测试背景
				if (this.canvasNode && this.ctx) {
					this.drawTestBackground()
				}
			}
		},

		/**
		 * 获取网络状态
		 */
		getNetworkType() {
			return new Promise((resolve) => {
				uni.getNetworkType({
					success: resolve,
					fail: () => resolve({
						networkType: 'unknown'
					})
				})
			})
		},

		/**
		 * 下载文件
		 */
		downloadFile(url) {
			return new Promise((resolve, reject) => {
				uni.downloadFile({
					url: url,
					success: (res) => {
						if (res.statusCode === 200) {
							resolve(res)
						} else {
							reject(new Error(`下载失败，状态码: ${res.statusCode}`))
						}
					},
					fail: (error) => {
						reject(error)
					}
				})
			})
		},

		/**
		 * 获取图片信息
		 */
		getImageInfo(src) {
			return new Promise((resolve, reject) => {
				uni.getImageInfo({
					src: src,
					success: resolve,
					fail: reject
				})
			})
		},

		/**
		 * 初始化canvas
		 */
		initCanvas() {
			const query = uni.createSelectorQuery().in(this)
			query.select(`#myCanvas${this.swiperIndex}`)
				.fields({
					node: true,
					size: true
				})
				.exec(res => {
					if (res[0]) {
						this.canvasNode = res[0].node
						this.canvasDisplayWidth = res[0].width
						this.canvasDisplayHeight = res[0].height
						this.ctx = this.canvasNode.getContext('2d')
						this.dpr = uni.getSystemInfoSync().pixelRatio

						console.log(`Canvas ${this.swiperIndex} 初始化成功`, {
							displayWidth: this.canvasDisplayWidth,
							displayHeight: this.canvasDisplayHeight,
							dpr: this.dpr
						})

						// 先绘制测试背景，确保canvas正常工作
						this.drawTestBackground()

						// 如果图片已经加载好，再设置canvas
						if (this.bgImgPath) {
							this.setupCanvas()
						}
					} else {
						console.error(`Canvas ${this.swiperIndex} 初始化失败`)
					}
				})
		},

		/**
		 * 设置canvas
		 */
		setupCanvas() {
			if (!this.canvasNode || !this.ctx) {
				console.log(`Canvas ${this.swiperIndex} - Canvas节点或上下文未准备好，跳过设置`);
				return
			}

			console.log(`Canvas ${this.swiperIndex} - 开始设置Canvas:`, {
				canvas宽度: this.canvasWidth,
				canvas高度: this.canvasHeight,
				图片路径: this.bgImgPath,
				dpr: this.dpr
			});

			// 设置canvas实际尺寸（考虑DPR）
			this.canvasNode.width = this.canvasWidth * this.dpr
			this.canvasNode.height = this.canvasHeight * this.dpr
			this.ctx.scale(this.dpr, this.dpr)

			if (this.bgImgPath) {
				console.log(`Canvas ${this.swiperIndex} - 开始加载背景图片:`, this.bgImgPath);
				// 有图片时加载图片
				const img = this.canvasNode.createImage()
				img.src = this.bgImgPath

				img.onload = () => {
					console.log(`Canvas ${this.swiperIndex} - 背景图片加载成功，开始绘制`);
					// 先清空Canvas
					this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)

					// 直接1:1绘制图片
					this.ctx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight)

					// 绘制标记
					this.drawMarkers()

					// 绘制Canvas标识
					this.drawCanvasIndicator()

					console.log(`Canvas ${this.swiperIndex} - Canvas绘制完成`);
				}

				img.onerror = (error) => {
					console.error(`Canvas ${this.swiperIndex} - 背景图片加载失败:`, error);
					// 图片加载失败时绘制测试背景
					this.drawTestBackground()
				}
			} else {
				console.log(`Canvas ${this.swiperIndex} - 没有背景图片，绘制测试背景`);
				// 没有图片时绘制测试背景
				this.drawTestBackground()
			}
		},

		/**
		 * 绘制测试背景（用于调试）
		 */
		drawTestBackground() {
			if (!this.ctx) {
				console.error('Canvas context not available')
				return
			}

			// 设置默认canvas尺寸如果还没有图片
			if (!this.canvasWidth || !this.canvasHeight) {
				this.canvasWidth = 750
				this.canvasHeight = 1000
			}

			// 设置canvas实际尺寸（考虑DPR）
			this.canvasNode.width = this.canvasWidth * this.dpr
			this.canvasNode.height = this.canvasHeight * this.dpr
			this.ctx.scale(this.dpr, this.dpr)

			console.log(`Canvas ${this.swiperIndex} 绘制测试背景`, {
				canvasWidth: this.canvasWidth,
				canvasHeight: this.canvasHeight
			})

			// 绘制一个渐变背景用于测试
			const gradient = this.ctx.createLinearGradient(0, 0, this.canvasWidth, this.canvasHeight)
			gradient.addColorStop(0, '#f0f0f0')
			gradient.addColorStop(1, '#e0e0e0')

			this.ctx.fillStyle = gradient
			this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight)

			// 绘制一些测试文字
			this.ctx.fillStyle = '#333'
			this.ctx.font = '40px Arial'
			this.ctx.textAlign = 'left'
			this.ctx.textBaseline = 'top'
			this.ctx.fillText(`Canvas测试 ${this.swiperIndex + 1}`, 50, 100)
			this.ctx.fillText('等待图片加载...', 50, 150)

			// 绘制字符的可点击区域（用于调试）
			if (this.list && this.list.length > 0) {
				this.ctx.strokeStyle = '#00ff00'
				this.ctx.lineWidth = 2
				this.ctx.setLineDash([5, 5]) // 虚线

				this.list.forEach(item => {
					if (item.chars && Array.isArray(item.chars)) {
						item.chars.forEach(char => {
							// 适配原格式：从locations中找到当前canvas的位置
							if (char.locations && Array.isArray(char.locations)) {
								const location = char.locations.find(loc => loc.imageIndex === this
									.swiperIndex)
								if (location) {
									// 绘制字符边界框
									this.ctx.strokeRect(location.l, location.t, location.w, location.h)

									// 绘制字符中心点
									this.ctx.fillStyle = '#ff0000'
									const center = {
										x: location.l + location.w / 2,
										y: location.t + location.h / 2
									}
									this.ctx.fillRect(center.x - 2, center.y - 2, 4, 4)

									// 标注字符
									this.ctx.fillStyle = '#000'
									this.ctx.font = '20px Arial'
									this.ctx.fillText(char.zi || '?', location.l, location.t - 5)
								}
							}
						})
					}
				})

				this.ctx.setLineDash([]) // 重置为实线
			}

			// 绘制标记
			this.drawMarkers()

			// 绘制Canvas标识
			this.drawCanvasIndicator()
		},

		/**
		 * 判断是否为标点错误
		 */
		isPunctuationError(char) {
			return char.type && (
				char.type.includes('标点') ||
				char.type === '对话标点缺失' ||
				char.type === '标点使用不当' ||
				char.type.includes('引号') ||
				char.type.includes('句号') ||
				char.type.includes('逗号') ||
				char.type.includes('问号') ||
				char.type.includes('感叹号') ||
				char.type.includes('冒号') ||
				char.type.includes('分号') ||
				char.type.includes('省略号') ||
				char.code && char.code.startsWith('BD') // errorBiaoDians的code都是BD开头
			)
		},

		/**
		 * 判断是否为不雅句子（errorJuZis）
		 */
		isErrorSentence(char) {
			// 如果是用户修正的错字，直接返回false
			if (char.type === '用户修正') {
				return false;
			}

			// errorJuZis数据特征：有reason、correct、locations、ziEIndex、ziSIndex
			console.log(`Canvas ${this.swiperIndex} - isErrorSentence判断:`, {
				reason: char.reason,
				correct: char.correct,
				type: char.type,
				code: char.code,
				xiuCi: char.xiuCi,
				shangXi: char.shangXi,
				zi: char.zi,
				ziEIndex: char.ziEIndex,
				ziSIndex: char.ziSIndex,
				locations: char.locations?.length || 0
			})

			// 简化判断逻辑：只要有errorJuZis的核心特征就认为是不雅句子
			const hasErrorJuZisFields = char.reason !== undefined &&
				char.correct !== undefined &&
				char.locations !== undefined &&
				Array.isArray(char.locations) &&
				char.locations.length > 0 &&
				char.ziEIndex !== undefined &&
				char.ziSIndex !== undefined

			// 排除明确的其他类型：
			// 1. 如果有shangXi或xiuCi字段，说明是妙句或修辞句子
			// 2. 如果是标点错误，也要排除
			// 3. 如果是用户修正，也要排除
			const notOtherTypes = char.shangXi === undefined &&
				char.xiuCi === undefined &&
				char.type !== '用户修正' &&
				!this.isPunctuationError(char)

			const result = hasErrorJuZisFields && notOtherTypes

			console.log(`Canvas ${this.swiperIndex} - isErrorSentence判断结果:`, {
				hasErrorJuZisFields,
				notOtherTypes,
				finalResult: result,
				判断依据: {
					"有reason": char.reason !== undefined,
					"有correct": char.correct !== undefined,
					"有locations": char.locations !== undefined && Array.isArray(char.locations) && char
						.locations.length > 0,
					"有ziEIndex": char.ziEIndex !== undefined,
					"有ziSIndex": char.ziSIndex !== undefined,
					"无shangXi": char.shangXi === undefined,
					"无xiuCi": char.xiuCi === undefined,
					"不是用户修正": char.type !== '用户修正',
					"不是标点错误": !this.isPunctuationError(char),
					"isPunctuationError结果": this.isPunctuationError(char)
				}
			})

			return result
		},

		/**
		 * 处理批改数据
		 */
		processCorrectData() {
			if (!this.list || this.list.length === 0) {
				console.log(`Canvas ${this.swiperIndex} - 没有数据需要处理`)
				return
			}

			console.log(`Canvas ${this.swiperIndex} - 开始处理数据，list长度:`, this.list.length)
			console.log(`Canvas ${this.swiperIndex} - 完整list数据:`, JSON.stringify(this.list))

			// 检查数据格式并转换
			let processedList = this.list

			// 如果第一个元素直接包含errorJuZis的特征（reason, correct, locations），说明需要转换格式
			if (this.list.length > 0 && this.list[0].reason !== undefined && this.list[0].correct !== undefined && this
				.list[0].locations !== undefined) {
				console.log(`Canvas ${this.swiperIndex} - 检测到errorJuZis直接格式，进行格式转换`)

				// 将errorJuZis格式转换为chars格式
				processedList = [{
					chars: this.list.map(errorJuZi => ({
						...errorJuZi,
						// 确保数据完整性
						reason: errorJuZi.reason,
						correct: errorJuZi.correct,
						locations: errorJuZi.locations,
						ziEIndex: errorJuZi.ziEIndex,
						ziSIndex: errorJuZi.ziSIndex
					}))
				}]

				console.log(`Canvas ${this.swiperIndex} - 格式转换完成，转换后数据:`, {
					originalLength: this.list.length,
					convertedLength: processedList[0].chars.length,
					sampleConvertedData: processedList[0].chars.slice(0, 2)
				})
			}

			// 适配原本的errorZis、errorBiaoDians和goodJuZis格式
			this.errorChars = this.getErrorCharsFromOriginalFormat(processedList)
			this.missingChars = [] // 暂时不处理漏写字

			// 重新构建markedChars，包含位置信息
			this.markedChars = []
			let errorJuZisCount = 0 // 统计errorJuZis数量
			let allCharsWithReasonCorrect = [] // 所有包含reason/correct的字符

			processedList.forEach((item, listIndex) => {
				console.log(`Canvas ${this.swiperIndex} - 处理item ${listIndex}:`, item)

				if (item.chars && Array.isArray(item.chars)) {
					item.chars.forEach((char, charIndex) => {
						// 记录所有包含reason/correct的字符，用于调试
						if (char.reason !== undefined || char.correct !== undefined) {
							allCharsWithReasonCorrect.push({
								listIndex,
								charIndex,
								reason: char.reason,
								correct: char.correct,
								type: char.type,
								xiuCi: char.xiuCi,
								shangXi: char.shangXi,
								zi: char.zi,
								ziEIndex: char.ziEIndex,
								ziSIndex: char.ziSIndex,
								isGoodSentence: this.isGoodSentence(char),
								isRhetoricalSentence: this.isRhetoricalSentence(char),
								isErrorSentence: this.isErrorSentence(char),
								fullChar: char // 完整字符数据
							})
						}

						// 特别检查errorJuZis
						if (this.isErrorSentence(char)) {
							errorJuZisCount++
							console.log(
								`Canvas ${this.swiperIndex} - 发现errorJuZis ${errorJuZisCount}:`, {
								listIndex,
								charIndex,
								reason: char.reason,
								correct: char.correct,
								type: char.type,
								xiuCi: char.xiuCi,
								ziEIndex: char.ziEIndex,
								ziSIndex: char.ziSIndex,
								locations: char.locations,
								completeCharData: char
							})
						}

						// 对于原格式的错别字、标点错误、妙句、修辞句子和不雅句子，自动标注
						if (char.type === "错别字" || char.type === "用户修正" || this.isPunctuationError(char) || this
							.isGoodSentence(char) || this.isRhetoricalSentence(char) || this
								.isErrorSentence(char)) {
							this.markedChars.push({
								...char,
								listIndex,
								charIndex
							})
						}
					})
				}
			})

			// 详细分析所有包含reason/correct的字符
			console.log(`Canvas ${this.swiperIndex} - 所有包含reason/correct的字符分析:`)
			allCharsWithReasonCorrect.forEach((charInfo, index) => {
				console.log(`  字符${index + 1}:`, {
					reason: charInfo.reason,
					correct: charInfo.correct,
					type: charInfo.type,
					xiuCi: charInfo.xiuCi,
					shangXi: charInfo.shangXi,
					zi: charInfo.zi,
					ziEIndex: charInfo.ziEIndex,
					ziSIndex: charInfo.ziSIndex,
					判断结果: {
						isGoodSentence: charInfo.isGoodSentence,
						isRhetoricalSentence: charInfo.isRhetoricalSentence,
						isErrorSentence: charInfo.isErrorSentence
					}
				})
			})

			console.log(`Canvas ${this.swiperIndex} - 发现errorJuZis总数:`, errorJuZisCount)
			console.log(`Canvas ${this.swiperIndex} - markedChars总数:`, this.markedChars.length)
			console.log(`Canvas ${this.swiperIndex} - 不雅句子数量:`, this.markedChars.filter(char => this.isErrorSentence(
				char)).length)
			console.log(`Canvas ${this.swiperIndex} - markedChars详情:`, this.markedChars.map(char => ({
				type: char.type,
				reason: char.reason,
				shangXi: char.shangXi,
				xiuCi: char.xiuCi,
				zi: char.zi,
				isErrorSentence: this.isErrorSentence(char)
			})))

			// 如果canvas已准备好，重新绘制
			if (this.ctx && this.bgImgPath) {
				this.redraw()
			}

			console.log(`Canvas ${this.swiperIndex} - 完成所有不雅句子绘制`)

			// 提取并发送reason数据到父组件
			this.emitReasonData()
		},

		/**
		 * 判断是否为妙句
		 */
		isGoodSentence(char) {
			return char.shangXi !== undefined ||
				(char.type && char.type.includes('妙句'))
		},

		/**
		 * 判断是否为修辞句子
		 */
		isRhetoricalSentence(char) {
			// 如果是用户修正的错字，直接返回false
			if (char.type === '用户修正') {
				return false;
			}

			return char.xiuCi !== undefined ||
				(char.reason !== undefined && char.type !== undefined && char.type !== "错别字" && char.type !== "不雅句子" && char.type !== "用户修正" &&
					!this.isPunctuationError(char)) ||
				(char.type && (char.type.includes('修辞') || char.type.includes('比喻') || char.type.includes('拟人') || char
					.type.includes('排比') || char.type.includes('设问') || char.type.includes('反问')))
		},

		/**
		 * 从原格式中提取错误字符
		 */
		getErrorCharsFromOriginalFormat(list) {
			const errorChars = []
			list.forEach(item => {
				if (item.chars && Array.isArray(item.chars)) {
					item.chars.forEach(char => {
						if (char.type === "错别字" || this.isPunctuationError(char) || this
							.isGoodSentence(char) || this.isRhetoricalSentence(char) || this
								.isErrorSentence(char)) {
							errorChars.push(char)
						}
					})
				}
			})
			return errorChars
		},

		/**
		 * 获取字符中心点（适配原格式）
		 */
		getCharCenterFromOriginalFormat(char, currentImageIndex) {
			// 从locations中找到当前canvas对应的位置信息
			const location = char.locations.find(loc => loc.imageIndex === currentImageIndex)
			if (location) {
				return {
					x: location.l + location.w / 2,
					y: location.t + location.h / 2
				}
			}
			return null
		},

		/**
		 * 检查点击是否在字符区域内（适配原格式）
		 */
		isClickInCharFromOriginalFormat(x, y, char, currentImageIndex, padding = 30) {
			const location = char.locations.find(loc => loc.imageIndex === currentImageIndex)
			if (!location) return false

			const expandedL = location.l - padding
			const expandedT = location.t - padding
			const expandedR = location.l + location.w + padding
			const expandedB = location.t + location.h + padding

			return x >= expandedL && x <= expandedR && y >= expandedT && y <= expandedB
		},

		/**
		 * 绘制标记
		 */
		drawMarkers() {
			if (!this.ctx) return

			// 检查是否全部正确（errorZis字段为空）
			this.checkAndDrawCorrectMark()

			// 绘制错别字标记
			this.drawErrorMarkers()

			// 绘制优美句子的波浪线
			this.drawGoodSentenceMarkers()

			// 绘制不雅句子波浪线
			this.drawErrorSentenceMarkers()
		},

		/**
		 * 绘制错别字标记
		 */
		drawErrorMarkers() {
			if (!this.markedChars || this.markedChars.length === 0) {
				return
			}

			this.ctx.strokeStyle = '#ff0000'
			this.ctx.fillStyle = '#ff0000'
			this.ctx.lineWidth = Math.max(1, this.lineWidth + 1)
			this.ctx.font = `bold ${Math.round(this.fontSize * 1.2)}px Arial`

			this.markedChars.forEach((char, index) => {
				// 只有纯妙句和修辞句子（不是错误字符）才跳过圆圈绘制
				const isError = char.type === "错别字" || char.type === "用户修正" || this.isPunctuationError(char)
				if ((this.isGoodSentence(char) || this.isRhetoricalSentence(char)) && !isError) {
					return
				}

				// 区分错别字和标点错误的绘制逻辑
				if (char.type === "错别字" || char.type === "用户修正") {
					// 错别字和用户修正：绘制单个圆圈
					const center = this.getCharCenterFromOriginalFormat(char, this.swiperIndex)
					if (!center) return

					// 使用稍大的圈圈半径，确保更明显 lzl修改
					const enlargedRadius = this.circleSize + 20

					// 绘制红色圆圈
					this.ctx.beginPath()
					this.ctx.arc(center.x, center.y, enlargedRadius, 0, Math.PI * 2)
					this.ctx.stroke()
				} else if (this.isPunctuationError(char)) {
					// 标点错误：只在首个和最后一个location位置画圈圈
					if (!char.locations || !Array.isArray(char.locations)) {
						return
					}

					const locations = char.locations.filter(loc => loc.imageIndex === this.swiperIndex)

					if (!locations || locations.length === 0) return

					// 使用稍大的圈圈半径，确保更明显 lzl修改
					const enlargedRadius = this.circleSize + 20

					// 绘制首个位置的圆圈
					if (locations.length > 0) {
						const firstLocation = locations[0]
						const firstCenter = {
							x: firstLocation.l + firstLocation.w / 2,
							y: firstLocation.t + firstLocation.h / 2
						}

						this.ctx.beginPath()
						this.ctx.arc(firstCenter.x, firstCenter.y, enlargedRadius, 0, Math.PI * 2)
						this.ctx.stroke()
					}

					// 如果有多个位置，绘制最后一个位置的圆圈
					if (locations.length > 1) {
						const lastLocation = locations[locations.length - 1]
						const lastCenter = {
							x: lastLocation.l + lastLocation.w / 2,
							y: lastLocation.t + lastLocation.h / 2
						}

						this.ctx.beginPath()
						this.ctx.arc(lastCenter.x, lastCenter.y, enlargedRadius, 0, Math.PI * 2)
						this.ctx.stroke()
					}
				}
			})
		},

		/**
		 * 绘制漏写字标记
		 */
		drawMissingMarkers() {
			if (!this.missingChars || this.missingChars.length === 0) return

			this.ctx.strokeStyle = '#ffaa00'
			this.ctx.lineWidth = this.lineWidth

			this.missingChars.forEach(char => {
				const center = getCharCenter(char.wz)

				// 绘制橙色方框
				this.ctx.strokeRect(
					center.x - this.circleSize,
					center.y - this.circleSize,
					this.circleSize * 2,
					this.circleSize * 2
				)
			})
		},

		/**
		 * 绘制妙句波浪线标记
		 */
		drawGoodSentenceMarkers() {
			if (!this.markedChars || this.markedChars.length === 0) {
				return
			}

			// 筛选出妙句
			const goodSentences = this.markedChars.filter(char => this.isGoodSentence(char))

			goodSentences.forEach((goodSentence, index) => {
				// 获取当前canvas对应的所有位置信息
				const locations = goodSentence.locations.filter(loc => loc.imageIndex === this.swiperIndex)

				// 为每个字符位置单独绘制波浪线
				locations.forEach((location, locationIndex) => {
					// 根据每个字符的具体坐标绘制波浪线
					const startX = location.l
					const startY = location.t + location.h + 8 // 字符下方8像素处开始
					const width = location.w

					// 为每个字符绘制波浪线，增大波纹幅度
					this.drawWavyLine(startX, startY, width, 15) // 增大waveHeight到15，让波纹更明显

					// 在第一个字符的右上角绘制圆圈数字
					if (locationIndex === 0) {
						this.drawGoodSentenceNumber(location, index + 1)
					}
				})
			})
		},

		/**
		 * 绘制妙句序号
		 * @param {Object} location 第一个字符的位置信息
		 * @param {Number} number 序号
		 */
		drawGoodSentenceNumber(location, number) {
			// 数字显示在第一个字符的左上角
			const textX = location.l // 字符左边界X坐标
			const textY = location.t - 5 // 字符上方5像素

			// 绘制红色数字
			this.ctx.fillStyle = '#ff0000'
			this.ctx.font = `bold ${Math.round(this.fontSize * 1.5)}px Arial`
			this.ctx.textAlign = 'left' // 左对齐，确保数字在左上角
			this.ctx.textBaseline = 'bottom'
			this.ctx.fillText(number.toString(), textX, textY)
		},

		/**
		 * 绘制波浪线（参考canvas.vue的实现）
		 * @param {number} x1 起始x坐标
		 * @param {number} y1 起始y坐标
		 * @param {number} width 宽度
		 * @param {number} waveHeight 波浪幅度
		 */
		drawWavyLine(x1, y1, width, waveHeight = 10) {
			const x2 = x1 + width
			const y2 = y1
			const waveCount = Math.max(2, Math.floor(width / 50)) // 根据宽度动态计算波浪数量

			const dx = (x2 - x1) / waveCount
			const dy = (y2 - y1) / waveCount
			let currentX = x1
			let currentY = y1

			this.ctx.beginPath()
			this.ctx.moveTo(x1, y1)

			for (let i = 0; i < waveCount; i++) {
				const cx = currentX + dx / 2
				const cy = currentY + dy / 2 + (i % 2 === 0 ? -waveHeight : waveHeight)
				const nextX = currentX + dx
				const nextY = currentY + dy
				this.ctx.quadraticCurveTo(cx, cy, nextX, nextY)
				currentX = nextX
				currentY = nextY
			}

			this.ctx.strokeStyle = '#ff0000'
			this.ctx.lineWidth = Math.max(3, this.lineWidth)
			this.ctx.stroke()
		},

		/**
		 * 绘制不雅句子波浪线标记
		 */
		drawErrorSentenceMarkers() {
			if (!this.markedChars || this.markedChars.length === 0) {
				console.log(`Canvas ${this.swiperIndex} - 没有markedChars，跳过不雅句子绘制`)
				return
			}

			// 筛选出不雅句子
			const errorSentences = this.markedChars.filter(char => this.isErrorSentence(char))

			console.log(`Canvas ${this.swiperIndex} - 开始绘制不雅句子，总数:`, errorSentences.length)

			// 根据reason和correct字段去重，避免重复绘制
			const uniqueErrorSentences = []
			const seenSentences = new Set()

			errorSentences.forEach((errorSentence) => {
				// 使用reason+correct作为唯一标识
				const uniqueKey = `${errorSentence.reason}_${errorSentence.correct}`
				if (!seenSentences.has(uniqueKey)) {
					seenSentences.add(uniqueKey)
					uniqueErrorSentences.push(errorSentence)
					console.log(`Canvas ${this.swiperIndex} - 添加唯一不雅句子:`, {
						reason: errorSentence.reason,
						correct: errorSentence.correct,
						uniqueKey: uniqueKey
					})
				} else {
					console.log(`Canvas ${this.swiperIndex} - 跳过重复不雅句子:`, {
						reason: errorSentence.reason,
						correct: errorSentence.correct,
						uniqueKey: uniqueKey
					})
				}
			})

			console.log(`Canvas ${this.swiperIndex} - 去重后不雅句子数量:`, uniqueErrorSentences.length)

			uniqueErrorSentences.forEach((errorSentence, sentenceIndex) => {
				console.log(`Canvas ${this.swiperIndex} - 绘制不雅句子 ${sentenceIndex + 1}:`, {
					reason: errorSentence.reason,
					correct: errorSentence.correct,
					totalLocations: errorSentence.locations?.length || 0
				})

				// 确保locations存在且为数组
				if (!errorSentence.locations || !Array.isArray(errorSentence.locations)) {
					console.warn(`Canvas ${this.swiperIndex} - 不雅句子 ${sentenceIndex + 1} 缺少locations数据`)
					return
				}

				// 获取当前canvas对应的所有位置信息
				const locations = errorSentence.locations.filter(loc => loc.imageIndex === this.swiperIndex)

				console.log(`Canvas ${this.swiperIndex} - 不雅句子 ${sentenceIndex + 1} 在当前canvas的位置数量:`, locations
					.length)

				if (locations.length === 0) {
					console.log(`Canvas ${this.swiperIndex} - 不雅句子 ${sentenceIndex + 1} 在当前canvas无位置信息`)
					return
				}

				// 为每个字符位置单独绘制蓝色波浪线
				locations.forEach((location, locationIndex) => {
					console.log(
						`Canvas ${this.swiperIndex} - 绘制位置 ${locationIndex + 1}/${locations.length}:`, {
						l: location.l,
						t: location.t,
						w: location.w,
						h: location.h,
						imageIndex: location.imageIndex
					})

					// 根据每个字符的具体坐标绘制波浪线
					const startX = location.l
					const startY = location.t + location.h + 8 // 字符下方8像素处开始
					const width = location.w

					// 为每个字符绘制蓝色波浪线，增大波纹幅度
					this.drawErrorSentenceWavyLine(startX, startY, width, 15) // 增大waveHeight到15，让波纹更明显

					// 在第一个字符的上方绘制序号
					if (locationIndex === 0) {
						this.drawErrorSentenceNumber(location, sentenceIndex + 1)
					}
				})

				console.log(
					`Canvas ${this.swiperIndex} - 完成绘制不雅句子 ${sentenceIndex + 1}，共绘制 ${locations.length} 个位置`
				)
			})

			console.log(`Canvas ${this.swiperIndex} - 完成所有不雅句子绘制`)
		},

		/**
		 * 绘制不雅句子序号
		 * @param {Object} location 第一个字符的位置信息
		 * @param {Number} number 序号
		 */
		drawErrorSentenceNumber(location, number) {
			// 数字显示在第一个字符的左上角（而不是上方中央）
			const textX = location.l // 字符左边界X坐标
			const textY = location.t - 5 // 字符上方5像素

			// 绘制蓝色数字
			this.ctx.fillStyle = '#1E90FF' // 蓝色
			this.ctx.font = `bold ${Math.round(this.fontSize * 1.5)}px Arial`
			this.ctx.textAlign = 'left' // 左对齐，确保数字在左上角
			this.ctx.textBaseline = 'bottom'
			this.ctx.fillText(number.toString(), textX, textY)
		},

		/**
		 * 绘制不雅句子专用的蓝色波浪线
		 * @param {number} x1 起始x坐标
		 * @param {number} y1 起始y坐标
		 * @param {number} width 宽度
		 * @param {number} waveHeight 波浪幅度
		 */
		drawErrorSentenceWavyLine(x1, y1, width, waveHeight = 10) {
			console.log(`Canvas ${this.swiperIndex} - 正在绘制蓝色波浪线:`, {
				x1,
				y1,
				width,
				waveHeight
			})

			const x2 = x1 + width
			const y2 = y1
			const waveCount = Math.max(2, Math.floor(width / 50)) // 根据宽度动态计算波浪数量

			const dx = (x2 - x1) / waveCount
			const dy = (y2 - y1) / waveCount
			let currentX = x1
			let currentY = y1

			this.ctx.beginPath()
			this.ctx.moveTo(x1, y1)

			for (let i = 0; i < waveCount; i++) {
				const cx = currentX + dx / 2
				const cy = currentY + dy / 2 + (i % 2 === 0 ? -waveHeight : waveHeight)
				const nextX = currentX + dx
				const nextY = currentY + dy
				this.ctx.quadraticCurveTo(cx, cy, nextX, nextY)
				currentX = nextX
				currentY = nextY
			}

			// 使用蓝色绘制波浪线
			this.ctx.strokeStyle = '#1E90FF' // 蓝色
			this.ctx.lineWidth = Math.max(5, this.lineWidth) // 加粗线条，便于观察
			this.ctx.stroke()

			console.log(`Canvas ${this.swiperIndex} - 蓝色波浪线绘制完成，颜色: #1E90FF, 线宽: ${Math.max(5, this.lineWidth)}`)
		},

		/**
		 * 处理触摸开始
		 */
		handleTouchStart(e) {
			const touch = e.touches[0]
			const canvasCoord = this.convertDisplayToCanvas(touch.x, touch.y)

			this.touchStartX = canvasCoord.x
			this.touchStartY = canvasCoord.y
			this.isMoving = false
		},

		/**
		 * 处理触摸移动
		 */
		handleTouchMove(e) {
			const touch = e.touches[0]
			const canvasCoord = this.convertDisplayToCanvas(touch.x, touch.y)

			const dx = Math.abs(canvasCoord.x - this.touchStartX)
			const dy = Math.abs(canvasCoord.y - this.touchStartY)

			if (dx > this.moveThreshold || dy > this.moveThreshold) {
				this.isMoving = true
			}
		},

		/**
		 * 处理触摸结束
		 */
		handleTouchEnd(e) {
			if (!this.isMoving) {
				// 这是一次点击
				this.handleClick(this.touchStartX, this.touchStartY)
			}
		},

		/**
		 * 处理点击事件
		 */
		handleClick(x, y) {
			console.log(`Canvas ${this.swiperIndex} - 点击位置:`, { x, y })

			// 遍历所有可点击的字符，检测是否点击了某个字符
			for (let charIndex = 0; charIndex < this.clickableChars.length; charIndex++) {
				const char = this.clickableChars[charIndex]

				// 检查字符的位置信息
				if (!char.wz || char.wz.l === undefined || char.wz.t === undefined ||
					char.wz.w === undefined || char.wz.h === undefined) {
					continue
				}

				// 增大点击检测范围，使用更大的padding
				const padding = Math.max(this.circleSize, 30)
				if (isClickInChar(x, y, char.wz, padding)) {
					console.log(`Canvas ${this.swiperIndex} - 点击了字符:`, char)

					// 直接按errorZis格式创建错字数据并发送给父组件
					const errorZiData = {
						zi: char.zi || '', // 错误的字
						correct: '', // 正确的字为空
						type: '用户修正',
						reason: '', // reason为空
						code: 'U001', // 用户修正的代码
						ziIndex: charIndex,
						locations: [{
							l: char.wz.l,
							t: char.wz.t,
							w: char.wz.w,
							h: char.wz.h,
							imageIndex: this.swiperIndex // 添加imageIndex以保持格式一致
						}], // 转换为标准locations格式
						swiperIndex: this.swiperIndex // 记录是第几页
					}

					// 通过事件发送错字数据到父组件，由父组件添加到errorZis并重新渲染
					this.$emit('addErrorZi', errorZiData)

					uni.showToast({
						title: `已将"${char.zi}"标记为错字`,
						icon: 'success'
					})
					return
				}
			}

			console.log(`Canvas ${this.swiperIndex} - 未点击到任何字符`)
		},

		/**
		 * 转换显示坐标到canvas坐标
		 */
		convertDisplayToCanvas(displayX, displayY) {
			if (!this.canvasDisplayWidth || !this.canvasDisplayHeight || !this.canvasWidth || !this.canvasHeight) {
				return {
					x: displayX,
					y: displayY
				}
			}

			const realX = displayX / this.canvasDisplayWidth * this.canvasWidth
			const realY = displayY / this.canvasDisplayHeight * this.canvasHeight

			return {
				x: realX,
				y: realY
			}
		},

		/**
		 * 重新绘制
		 */
		redraw() {
			if (!this.ctx || !this.bgImgPath) return

			// 清除canvas
			this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)

			// 重新绘制背景图片
			const img = this.canvasNode.createImage()
			img.src = this.bgImgPath

			img.onload = () => {
				this.ctx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight)
				this.drawMarkers()

				// 绘制Canvas标识
				this.drawCanvasIndicator()
			}
		},

		/**
		 * 绘制Canvas标识
		 */
		drawCanvasIndicator() {
			if (!this.ctx) return

			const text = `第${this.swiperIndex + 1}张`
			const padding = 20
			const fontSize = 36

			// 设置字体样式
			this.ctx.font = `bold ${fontSize}px Arial`
			this.ctx.textAlign = 'left'
			this.ctx.textBaseline = 'top'

			// 绘制红色文字
			this.ctx.fillStyle = '#ff0000'
			this.ctx.fillText(text, padding, padding)
		},

		/**
		 * 提取并发送reason数据到父组件
		 */
		emitReasonData() {
			const reasonData = {
				goodSentences: [],
				rhetoricalSentences: [],
				errorSentences: []
			}

			console.log(`Canvas ${this.swiperIndex} - markedChars:`, this.markedChars)

			// 提取优美句子的reason
			this.markedChars.forEach(char => {
				if (this.isGoodSentence(char) && char.reason) {
					reasonData.goodSentences.push({
						reason: char.reason,
						shangXi: char.shangXi || '优美句子'
					})
				}
			})

			// 提取修辞句子的reason
			this.markedChars.forEach(char => {
				const isRhetorical = this.isRhetoricalSentence(char)
				console.log(`Canvas ${this.swiperIndex} - char check:`, {
					char: char,
					isRhetorical: isRhetorical,
					hasReason: !!char.reason
				})

				if (isRhetorical && char.reason) {
					reasonData.rhetoricalSentences.push({
						reason: char.reason,
						xiuCi: char.xiuCi || char.type || '修辞手法'
					})
				}
			})

			// 提取不雅句子的reason
			this.markedChars.forEach(char => {
				if (this.isErrorSentence(char) && char.reason) {
					reasonData.errorSentences.push({
						reason: char.reason,
						correct: char.correct || '建议修改'
					})
				}
			})

			console.log(`Canvas ${this.swiperIndex} - 发送reasonData:`, reasonData)

			// 发送reasonData事件到父组件
			this.$emit('reasonData', {
				swiperIndex: this.swiperIndex,
				data: reasonData
			})
		},

		/**
		 * 处理attachs数据，提取可点击的字符信息
		 */
		processAttachsData(attachs) {
			this.originalAttachs = attachs
			this.clickableChars = []

			if (attachs && attachs.imageInfos && Array.isArray(attachs.imageInfos)) {
				// 根据swiperIndex找到对应的imageInfo
				const currentImageInfo = attachs.imageInfos[this.swiperIndex]

				if (currentImageInfo && currentImageInfo.ocrResult && currentImageInfo.ocrResult.chars) {
					this.clickableChars = currentImageInfo.ocrResult.chars
					console.log(`Canvas ${this.swiperIndex} - 提取到${this.clickableChars.length}个可点击字符`)
				} else {
					console.log(`Canvas ${this.swiperIndex} - 未找到对应的imageInfo或chars数据`)
				}
			}
		},

		/**
		 * 检查并绘制全对标记
		 */
		checkAndDrawCorrectMark() {
			// 检查是否有错别字数据
			const hasErrorChars = this.errorChars && this.errorChars.length > 0
			const hasMarkedChars = this.markedChars && this.markedChars.length > 0

			// 如果没有错误字符且没有已标记的字符，说明全部正确
			// 移除全对打赞和对号图片的绘制
		},

		/**
		 * 绘制全对标记
		 */
		drawCorrectCheckMark() {
			if (!this.ctx) return

			// 在居中位置绘制dui.png图片
			this.drawDuiImage()

			// 在右下角绘制赞的图片
			this.drawZanImage()
		},

		/**
		 * 绘制dui.png图片到居中位置
		 */
		drawDuiImage() {
			if (!this.ctx || !this.canvasNode) return

			const img = this.canvasNode.createImage()
			img.src = '/static/dui.png'

			img.onload = () => {
				// 设置图片大小和位置
				const imgSize = Math.min(this.canvasWidth, this.canvasHeight) * 0.5 // 图片大小调大一些
				const centerX = this.canvasWidth * 0.5 // 居中X坐标
				const centerY = this.canvasHeight * 0.8 // 居中Y坐标
				const imgX = centerX - imgSize / 2 // 图片左上角X坐标
				const imgY = centerY - imgSize / 2 // 图片左上角Y坐标

				// 绘制图片到居中位置
				this.ctx.drawImage(img, imgX, imgY, imgSize, imgSize)
			}

			img.onerror = (error) => {
				// 如果图片加载失败，在居中位置绘制文字替代
				this.ctx.fillStyle = '#ff0000'
				this.ctx.font = `bold ${Math.round(this.fontSize * 1.5)}px Arial`
				this.ctx.textAlign = 'center'
				this.ctx.textBaseline = 'middle'

				// 在居中位置显示"全对"文字
				const centerX = this.canvasWidth * 0.5
				const centerY = this.canvasHeight * 0.5
				this.ctx.fillText('全对', centerX, centerY)
			}
		},

		/**
		 * 绘制赞的图片到右下角
		 */
		drawZanImage() {
			if (!this.ctx || !this.canvasNode) return

			const img = this.canvasNode.createImage()
			img.src = '/static/zan.png'

			img.onload = () => {
				// 设置图片大小和位置
				const imgSize = Math.min(this.canvasWidth, this.canvasHeight) * 0.12 // 图片大小稍微调小一点
				const padding = 10 // 距离边缘的距离
				const imgX = this.canvasWidth - imgSize - padding // 右下角X坐标
				const imgY = this.canvasHeight - imgSize - padding // 右下角Y坐标

				// 绘制图片到右下角
				this.ctx.drawImage(img, imgX, imgY, imgSize, imgSize)
			}

			img.onerror = (error) => {
				// 如果图片加载失败，在右下角绘制一个文字替代
				this.ctx.fillStyle = '#ff6600'
				this.ctx.font = `bold ${Math.round(this.fontSize * 0.6)}px Arial`
				this.ctx.textAlign = 'right'
				this.ctx.textBaseline = 'bottom'

				// 确保文字也在右下角
				const textX = this.canvasWidth - 20
				const textY = this.canvasHeight - 20
				this.ctx.fillText('👍', textX, textY)
			}
		}
	},

	beforeDestroy() {
		// 清理资源
		if (this.canvasNode) {
			this.canvasNode = null
			this.ctx = null
		}
	}
}
</script>

<style>
.container {
	position: relative;
}
</style>